//@ts-nocheck
const { L }: any = window;
//坐标转换
L.CoordConver = function () {
  /**84转火星*/
  this.gps84_To_gcj02 = function (lng, lat) {
    let dLat = transformLat(lng - 105.0, lat - 35.0);
    let dLng = transformLng(lng - 105.0, lat - 35.0);
    const radLat = (lat / 180.0) * pi;
    let magic = Math.sin(radLat);
    magic = 1 - ee * magic * magic;
    const sqrtMagic = Math.sqrt(magic);
    dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * pi);
    dLng = (dLng * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * pi);
    const mgLat = lat + dLat;
    const mgLng = lng + dLng;
    const newCoord = {
      lng: mgLng,
      lat: mgLat,
    };
    return newCoord;
  };
  /**火星转84*/
  this.gcj02_To_gps84 = function (lng, lat) {
    const coord = transform(lng, lat);
    const lontitude = lng * 2 - coord.lng;
    const latitude = lat * 2 - coord.lat;
    const newCoord = {
      lng: lontitude,
      lat: latitude,
    };
    return newCoord;
  };
  // eslint-disable-next-line
  let pi = 3.1415926535897932384626;
  const a = 6378245.0;
  // eslint-disable-next-line
  let ee = 0.00669342162296594323;
  function transform(lng, lat) {
    let dLat = transformLat(lng - 105.0, lat - 35.0);
    let dLng = transformLng(lng - 105.0, lat - 35.0);
    const radLat = (lat / 180.0) * pi;
    let magic = Math.sin(radLat);
    magic = 1 - ee * magic * magic;
    const sqrtMagic = Math.sqrt(magic);
    dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * pi);
    dLng = (dLng * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * pi);
    const mgLat = lat + dLat;
    const mgLng = lng + dLng;
    const newCoord = {
      lng: mgLng,
      lat: mgLat,
    };
    return newCoord;
  }
  function transformLat(x, y) {
    let ret =
      -100.0 +
      2.0 * x +
      3.0 * y +
      0.2 * y * y +
      0.1 * x * y +
      0.2 * Math.sqrt(Math.abs(x));
    ret +=
      ((20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0) /
      3.0;
    ret +=
      ((20.0 * Math.sin(y * pi) + 40.0 * Math.sin((y / 3.0) * pi)) * 2.0) / 3.0;
    ret +=
      ((160.0 * Math.sin((y / 12.0) * pi) + 320 * Math.sin((y * pi) / 30.0)) *
        2.0) /
      3.0;
    return ret;
  }
  function transformLng(x, y) {
    let ret =
      300.0 +
      x +
      2.0 * y +
      0.1 * x * x +
      0.1 * x * y +
      0.1 * Math.sqrt(Math.abs(x));
    ret +=
      ((20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0) /
      3.0;
    ret +=
      ((20.0 * Math.sin(x * pi) + 40.0 * Math.sin((x / 3.0) * pi)) * 2.0) / 3.0;
    ret +=
      ((150.0 * Math.sin((x / 12.0) * pi) + 300.0 * Math.sin((x / 30.0) * pi)) *
        2.0) /
      3.0;
    return ret;
  }
};

L.coordConver = function () {
  return new L.CoordConver();
};

L.GridLayer.include({
  _transformCoords: function (_center) {
    let center = _center;
    if (this.options.corrdType == "gcj02") {
      center = L.coordConver().gps84_To_gcj02(_center.lng, _center.lat);
    }
    return center;
  },
  _setZoomTransform: function (level, _center, zoom) {
    let center = _center;
    if (center != undefined && this.options) {
      center = this._transformCoords(_center);
    }
    const scale = this._map.getZoomScale(zoom, level.zoom),
      translate = level.origin
        .multiplyBy(scale)
        .subtract(this._map._getNewPixelOrigin(center, zoom))
        .round();

    if (L.Browser.any3d) {
      L.DomUtil.setTransform(level.el, translate, scale);
    } else {
      L.DomUtil.setPosition(level.el, translate);
    }
  },
  _getTiledPixelBounds: function (_center) {
    let center = _center;
    if (center != undefined && this.options) {
      center = this._transformCoords(_center);
    }
    const map = this._map,
      mapZoom = map._animatingZoom
        ? Math.max(map._animateToZoom, map.getZoom())
        : map.getZoom(),
      scale = map.getZoomScale(mapZoom, this._tileZoom),
      pixelCenter = map.project(center, this._tileZoom).floor(),
      halfSize = map.getSize().divideBy(scale * 2);

    return new L.Bounds(
      pixelCenter.subtract(halfSize),
      pixelCenter.add(halfSize)
    );
  },
  _update_: function (center) {
    const map = this._map;
    if (!map) {
      return;
    }
    const zoom = this._clampZoom(map.getZoom());

    if (center === undefined) {
      center = map.getCenter();
    }
    if (this._tileZoom === undefined) {
      return;
    } // if out of minzoom/maxzoom

    const pixelBounds = this._getTiledPixelBounds(center),
      tileRange = this._pxBoundsToTileRange(pixelBounds),
      tileCenter = tileRange.getCenter(),
      queue = [],
      margin = this.options.keepBuffer,
      noPruneRange = new L.Bounds(
        tileRange.getBottomLeft().subtract([margin, -margin]),
        tileRange.getTopRight().add([margin, -margin])
      );

    // Sanity check: panic if the tile range contains Infinity somewhere.
    if (
      !(
        isFinite(tileRange.min.x) &&
        isFinite(tileRange.min.y) &&
        isFinite(tileRange.max.x) &&
        isFinite(tileRange.max.y)
      )
    ) {
      throw new Error("Attempted to load an infinite number of tiles");
    }

    for (const key in this._tiles) {
      const c = this._tiles[key].coords;
      if (
        c.z !== this._tileZoom ||
        !noPruneRange.contains(new L.Point(c.x, c.y))
      ) {
        this._tiles[key].current = false;
      }
    }

    // _update just loads more tiles. If the tile zoom level differs too much
    // from the map's, let _setView reset levels and prune old tiles.
    if (Math.abs(zoom - this._tileZoom) > 1) {
      this._setView(center, zoom);
      return;
    }

    // create a queue of coordinates to load tiles from
    for (let j = tileRange.min.y; j <= tileRange.max.y; j++) {
      for (let i = tileRange.min.x; i <= tileRange.max.x; i++) {
        const coords = new L.Point(i, j);
        coords.z = this._tileZoom;

        if (!this._isValidTile(coords)) {
          continue;
        }

        const tile = this._tiles[this._tileCoordsToKey(coords)];
        if (tile) {
          tile.current = true;
        } else {
          queue.push(coords);
        }
      }
    }

    // sort tile queue to load tiles in order of their distance to center
    queue.sort(function (a, b) {
      return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
    });

    if (queue.length !== 0) {
      // if it's the first batch of tiles to load
      if (!this._loading) {
        this._loading = true;
        // @event loading: Event
        // Fired when the grid layer starts loading tiles.
        this.fire("loading");
      }

      // create DOM fragment to append tiles in one batch
      const fragment = document.createDocumentFragment();

      for (let i = 0; i < queue.length; i++) {
        this._addTile(queue[i], fragment);
      }

      this._level.el.appendChild(fragment);
    }
  },
});
